WindowManagerService 就是位于 Framework 层的窗口管理服务,它的职责就是管理系统中的所有窗口。
Android中的窗口概念:屏幕上一块用于绘制各种UI元素并可以响应用户输入的一块矩形区域。从原理上来看,窗口的概念是独自占有一个Surface实例的显示区域。如Dialog、Activity的界面、壁纸、状态栏以及Toast等都是窗口。
WindowManagerService 添加一个窗口的过程,其实就是 WindowManagerService 为其分配一块 Surface 的过程,一块块的 Surface 在 WindowManagerService 的管理下有序的排列在屏幕上,Android 才得以呈现出多姿多彩的界面。
启动流程:
WindowManagerService由SystemServer.java启动,zygote进程会调用SyetemServer.java中的run方法开启相关服务。
SystemServer.java
frameworks/base/services/java/com/android/server/SystemServer.java
/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
new SystemServer().run();
}
1、SystemServer的run方法
private void run() {
try {
...
// Initialize the system context.
createSystemContext();
// 创建,启动SystemService和管理SystemService的生命周期
mSystemServiceManager = new SystemServiceManager(mSystemContext);
// 添加到本地服务的全局注册表中。
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
// Start services.
try {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
startBootstrapServices(); //开启引导服务
startCoreServices(); //开启核心服务
startOtherServices(); //开启其他服务
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
...
}
WindowManagerService在startOtherServices()方法中被启动,下面看startOtherServices()方法:
2、SystemServer的startOtherServices方法
private void startOtherServices() {
......
WindowManagerService wm = null;
SerialService serial = null;
NetworkTimeUpdateService networkTimeUpdater = null;
......
wm = WindowManagerService.main(context, inputManager,
mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL, !mFirstBoot, mOnlyCore);
ServiceManager.addService(Context.WINDOW_SERVICE, wm); //注册服务
......
mActivityManagerService.setWindowManager(wm); //和ActivityManagerService进行关联
inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
inputManager.start();
......
try {
wm.displayReady(); //初始化显示信息,尺寸,位置等
} catch (Throwable e) {
reportWtf("making display ready", e);
}
......
try {
wm.systemReady(); //通知WMS系统的初始化工作已完成
} catch (Throwable e) {
reportWtf("making Window Manager Service ready", e);
}
......
}
可以看到SystemServer启动WindowManagerService是调用WindowManagerService的main方法,WMS的main方法是运行在SystemServer的run方法中,换句话说就是运行在”system_server”线程中。下面进一步分析启动流程中涉及的主要方法。
二、WindowManagerService
1、WindowManagerService的main方法
public static WindowManagerService main(final Context context,
final InputManagerService im,
final boolean haveInputMethods, final boolean showBootMsgs,
final boolean onlyCore) {
final WindowManagerService[] holder = new WindowManagerService[1];
DisplayThread.getHandler().runWithScissors(new Runnable() {
@Override
public void run() {
holder[0] = new WindowManagerService(context, im,
haveInputMethods, showBootMsgs, onlyCore);
}
}, 0);
return holder[0];
}
DisplayThread extends ServiceThread,其中ServiceThread extends HandlerThread, 该Handler运行在名为"android.display"的线程中,这个runWithScissor方法是一个阻塞方法,会阻塞到直到WindowManagerService创建成功。由于WMS的main方法运行在SystemServer线程中("system_server"线程),所以"system_server"线程会处于等待状态,等到"android.display"执行完毕,下面看下runWithScissor的代码逻辑。
2、Handler的runWithScissors()
public final boolean runWithScissors(final Runnable r, long timeout) {
......
if (Looper.myLooper() == mLooper) {
r.run();
return true;
}
BlockingRunnable br = new BlockingRunnable(r);
return br.postAndWait(this, timeout);
}
runWithScissors同步运行指定的任务,如果当前线程与处理的线程相同,则立即运行,否则通过handler.post()方式执行。可以看出postAndWait(this, timeout)方法中是阻塞方法,直到任务执行完成,代码如下:
public boolean postAndWait(Handler handler, long timeout) {
if (!handler.post(this)) {
return false;
}
synchronized (this) {
if (timeout > 0) {
final long expirationTime = SystemClock.uptimeMillis() + timeout;
while (!mDone) {
long delay = expirationTime - SystemClock.uptimeMillis();
if (delay <= 0) {
return false; // timeout
}
try {
wait(delay);
} catch (InterruptedException ex) {
}
}
} else {
while (!mDone) {
try {
wait();
} catch (InterruptedException ex) {
}
}
}
}
return true;
}
至此,WindowManagerService已经创建完毕,下面看下WMS构造器中主要的初始化工作。
3、WindowManagerService构造方法
private WindowManagerService(Context context, InputManagerService inputManager,
boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {
mHaveInputMethods = haveInputMethods;
......
mInputManager = inputManager; // Must be before createDisplayContentLocked.
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
mDisplaySettings = new DisplaySettings(); //关于display的设置
mDisplaySettings.readSettingsLocked(); //读取/data目录下的display_settings.xml文件
mWallpaperControllerLocked = new WallpaperController(this);//控制壁纸窗口的可视性,排序等
mWindowPlacerLocked = new WindowSurfacePlacer(this); //定位窗口以及surface的位置
mLayersController = new WindowLayersController(this); //用于将图层分配给显示器上的窗口的控制器。
LocalServices.addService(WindowManagerPolicy.class, mPolicy); //窗体策略
mPointerEventDispatcher = new PointerEventDispatcher(mInputManager.monitorInput(TAG_WM));//接收输入事件
mFxSession = new SurfaceSession();//和surfaceflinger连接,创建管理surface实例
mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE); //管理显示属性
mDisplays = mDisplayManager.getDisplays();
for (Display display : mDisplays) {
createDisplayContentLocked(display); //创建对应的DisplayContent对象,DisplayContent描写叙述了一块能够绘制窗体的屏幕。
}
mKeyguardDisableHandler = new KeyguardDisableHandler(mContext, mPolicy); //键盘锁禁用
mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);//电源管理本地服务器接口
mPowerManagerInternal.registerLowPowerModeObserver( //监听低电
new PowerManagerInternal.LowPowerModeListener() {
@Override
public void onLowPowerModeChanged(boolean enabled) {
synchronized (mWindowMap) {
if (mAnimationsDisabled != enabled && !mAllowAnimationsInLowPowerMode) {
mAnimationsDisabled = enabled;
dispatchNewAnimatorScaleLocked(null);
}
}
}
});
mAnimationsDisabled = mPowerManagerInternal.getLowPowerModeEnabled();
mScreenFrozenLock = mPowerManager.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, "SCREEN_FROZEN");
mScreenFrozenLock.setReferenceCounted(false);
mAppTransition = new AppTransition(context, this); //过渡动画
mAppTransition.registerListenerLocked(mActivityManagerAppTransitionNotifier);
mBoundsAnimationController =
new BoundsAnimationController(mAppTransition, UiThread.getHandler());
mActivityManager = ActivityManagerNative.getDefault();
mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE); //应用程序操作的跟踪
AppOpsManager.OnOpChangedInternalListener opListener =
new AppOpsManager.OnOpChangedInternalListener() {
@Override public void onOpChanged(int op, String packageName) {
updateAppOpsState();
}
};
mAppOps.startWatchingMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, null, opListener);
mAppOps.startWatchingMode(AppOpsManager.OP_TOAST_WINDOW, null, opListener);
mContext.registerReceiver(mBroadcastReceiver, filter);
mSettingsObserver = new SettingsObserver(); //监听设置内容的变更
//唤醒锁,SCREEN_BRIGHT_WAKE_LOCK屏幕高亮显示,保持CPU运转,ON_AFTER_RELEASE保持屏幕亮一段时间,直到默认超时后黑屏
mHoldingScreenWakeLock = mPowerManager.newWakeLock(
PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG_WM);
mHoldingScreenWakeLock.setReferenceCounted(false);
//代表WindowManagerService在单独任务中执行动画和Surface操作的Singleton类。
mAnimator = new WindowAnimator(this);
mAllowTheaterModeWakeFromLayout = context.getResources().getBoolean(
com.android.internal.R.bool.config_allowTheaterModeWakeFromWindowLayout);
LocalServices.addService(WindowManagerInternal.class, new LocalService());
initPolicy(); //WindowManagerPolicy初始化,主要职责是负责UI。实现类PhoneWindowManager
// Add ourself to the Watchdog monitors.
Watchdog.getInstance().addMonitor(this);
.........
}